package com.ruibang.glass.material.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.material.constant.MaterialErrorCode;
import com.ruibang.glass.material.constant.MaterialWareHouseCode;
import com.ruibang.glass.material.domain.req.MaterialManagementReq;
import com.ruibang.glass.material.entity.MaterialALLInventoryManagement;
import com.ruibang.glass.material.entity.MaterialManagement;
import com.ruibang.glass.material.entity.MaterialWarehouseInfo;
import com.ruibang.glass.material.mapper.GMaterialWarehouseInfoMapper;
import com.ruibang.glass.material.mapper.MaterialManagementMapper;
import com.ruibang.glass.material.service.GMaterialALLInventoryManagementService;
import com.ruibang.glass.material.service.GMaterialManagementService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 物料管理表 服务实现类
 * </p>
 *
 * @author mameng
 * @since 2024-03-30
 */
@Service
public class MaterialManagementServiceImpl extends ServiceImpl<MaterialManagementMapper, MaterialManagement> implements GMaterialManagementService {

    @Autowired
    private GMaterialWarehouseInfoMapper warehouseInfoMapper;

    @Autowired
    private GMaterialALLInventoryManagementService gMaterialALLInventoryManagementService;

    @Autowired
    private RedisSingleService redisService;

    /***
     * 物料管理查询
     */
    @Override
    public IPage<MaterialManagement> getPage(MaterialManagementReq materialManagementReq) {
        LambdaQueryWrapper<MaterialManagement> queryWrapper = Wrappers.<MaterialManagement>lambdaQuery();

        if (StringUtils.isNotBlank(materialManagementReq.getBarcode())) {
            queryWrapper.like(MaterialManagement::getBarcode, materialManagementReq.getBarcode());
        }
        if (StringUtils.isNotBlank(materialManagementReq.getItemName())) {
            queryWrapper.like(MaterialManagement::getItemName, materialManagementReq.getItemName());
        }
        if (StringUtils.isNotBlank(materialManagementReq.getMaterialCode())) {
            queryWrapper.like(MaterialManagement::getMaterialCode, materialManagementReq.getMaterialCode());
        }
        if (StringUtils.isNotBlank(materialManagementReq.getSpecificationModel())) {
            queryWrapper.eq(MaterialManagement::getSpecificationModel, materialManagementReq.getSpecificationModel());
        }
        if (StringUtils.isNotBlank(materialManagementReq.getWarehouseCode())) {
            queryWrapper.eq(MaterialManagement::getWarehouseCode, materialManagementReq.getWarehouseCode());
        }
        if (CollectionUtils.isNotEmpty(materialManagementReq.getItemIds())) {
            queryWrapper.in(MaterialManagement::getId, materialManagementReq.getItemIds());
        }
        if (StringUtils.isNotBlank(materialManagementReq.getItemType())) {
            queryWrapper.notLikeRight(MaterialManagement::getItemType, materialManagementReq.getItemType());
        }


        Page<MaterialManagement> materialManagementPage = baseMapper.selectPage(new Page<>(materialManagementReq.getPageNo(), materialManagementReq.getPageSize()),
                queryWrapper.orderByDesc(MaterialManagement::getUpdateTime)
        );
        for (MaterialManagement materialManagement : materialManagementPage.getRecords()) {
            for (MaterialWareHouseCode ele : MaterialWareHouseCode.values()) {
                if (materialManagement.getWarehouseCode().equals(ele.getMsg())) {
                    materialManagement.setWarehouseCode(ele.getCode());
                }
            }
        }
        return materialManagementPage;
    }

    /***
     * 新增
     */
    @Override
    public void add(MaterialManagement materialManagement) {
        Long aLong = baseMapper.selectCount(Wrappers.<MaterialManagement>lambdaQuery().eq(MaterialManagement::getMaterialCode, materialManagement.getMaterialCode()));
        if (aLong > 0) {
            throw new ServiceException(MaterialErrorCode.MORE_ONE_MATERIAL_CODE.getCode(), MaterialErrorCode.MORE_ONE_MATERIAL_CODE.getMsg());
        }

        Long count = baseMapper.selectCount(Wrappers.<MaterialManagement>lambdaQuery()
                .eq(MaterialManagement::getItemName, materialManagement.getItemName())
                .eq(MaterialManagement::getSpecificationModel, materialManagement.getSpecificationModel())
                .eq(MaterialManagement::getUnit, materialManagement.getUnit()));
        if (count > 0) {
            throw new ServiceException(MaterialErrorCode.MATERIAL_INFORMATION_IS_EXIST.getCode(), MaterialErrorCode.MATERIAL_INFORMATION_IS_EXIST.getMsg());
        }
        baseMapper.insert(materialManagement);
    }

    @Override
    public List<MaterialManagement> getWarehouseByIds(List<String> itemIds) {
        List<MaterialManagement> list = this.list(Wrappers.<MaterialManagement>lambdaQuery().select(
                MaterialManagement::getId,
                MaterialManagement::getWarehouseCode)
                .isNotNull(MaterialManagement::getWarehouseCode)
                .in(MaterialManagement::getId, itemIds));
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> codes = list.stream().map(MaterialManagement::getWarehouseCode).collect(Collectors.toList());
            List<MaterialWarehouseInfo> infos = warehouseInfoMapper.selectList(Wrappers.<MaterialWarehouseInfo>lambdaQuery()
                    .select(MaterialWarehouseInfo::getWarehouseName,
                            MaterialWarehouseInfo::getWarehouseCode,
                            MaterialWarehouseInfo::getId).in(MaterialWarehouseInfo::getWarehouseCode, codes));
            Map<String, MaterialWarehouseInfo> infoMap = null;
            if (CollectionUtils.isNotEmpty(infos)) {
                infoMap = infos.stream().collect(Collectors.toMap(MaterialWarehouseInfo::getWarehouseCode, mw -> mw, (mw1, mw2) -> mw1));
            }
            if (infoMap != null) {
                for (MaterialManagement management : list) {
                    MaterialWarehouseInfo info = infoMap.get(management.getWarehouseCode());
                    if (info != null) {
                        management.setWarehouseId(info.getId());
                        management.setWarehouseName(info.getWarehouseName());
                    }
                }
            }
        }

        return list;
    }

    @Override
    public List<MaterialManagement> getMaterialInfo() {
        List<MaterialManagement> materialManagements = lambdaQuery().select(
                MaterialManagement::getMaterialCode, MaterialManagement::getItemName, MaterialManagement::getId
        ).eq(MaterialManagement::getWarehouseCode, MaterialWareHouseCode.YCLK_CK.getMsg()).list();
        if (CollectionUtils.isNotEmpty(materialManagements)) {
            List<String> materialCodes = materialManagements.stream().map(MaterialManagement::getMaterialCode).collect(Collectors.toList());
            List<MaterialALLInventoryManagement> materialInfo = gMaterialALLInventoryManagementService.getByMaterialCode(materialCodes);
            if (CollectionUtils.isNotEmpty(materialInfo)) {
                Map<String, List<MaterialALLInventoryManagement>> materialInfoMap = materialInfo.stream().collect(Collectors.groupingBy(MaterialALLInventoryManagement::getMaterialCode));
                for (MaterialManagement materialManagement : materialManagements) {
                    List<MaterialALLInventoryManagement> materialInfoList = materialInfoMap.get(materialManagement.getMaterialCode());
                    if (CollectionUtils.isNotEmpty(materialInfoList)) {
                        List<String> batchNumber = materialInfoList.stream().map(MaterialALLInventoryManagement::getBatchNumber).distinct().collect(Collectors.toList());
                        materialManagement.setBatchNumber(batchNumber);
                    }
                }
            }
        }
        return materialManagements;
    }

    @Override
    public IPage<MaterialManagement> queryMaterialChoose(MaterialManagementReq materialManagementReq) {

        Map<Object, Object> productMap = redisService.hmget(RedisKey.PRODUCT_MANAGEMENT_GROUP_TYPE);
        if (productMap != null && !productMap.isEmpty()) {
            List<String> productCodes = new ArrayList<>();
            for (Object obj : productMap.keySet()) {
                if (obj != null && StringUtils.isNotBlank(obj.toString())) {
                    productCodes.add(obj.toString());
                }
            }
            materialManagementReq.setProductCodes(productCodes);
        }

        IPage<MaterialManagement> page = baseMapper.queryPage(new Page<>(materialManagementReq.getPageNo(), materialManagementReq.getPageSize()),
                materialManagementReq);
        return page;
    }

    @Override
    public List<MaterialManagement> selectMaterialCPORBCPChoose(String wareHouseCode) {

        return null;
    }

    @Override
    public Map<String, String> getDictMap() {
        Map<String, String> dictMap = new HashMap<>();
        List<String> strings = baseMapper.dictNameList();
        for (String dict : strings) {
            dictMap.put(dict, dict);
        }
        return dictMap;
    }
}
